home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / install.e < prev    next >
Text File  |  2000-03-28  |  34KB  |  1,085 lines

  1. --          This file is part of SmallEiffel The GNU Eiffel Compiler.
  2. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  3. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr
  4. --                       http://SmallEiffel.loria.fr
  5. -- SmallEiffel is  free  software;  you can  redistribute it and/or modify it
  6. -- under the terms of the GNU General Public License as published by the Free
  7. -- Software  Foundation;  either  version  2, or (at your option)  any  later
  8. -- version. SmallEiffel is distributed in the hope that it will be useful,but
  9. -- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
  10. -- or  FITNESS FOR A PARTICULAR PURPOSE.   See the GNU General Public License
  11. -- for  more  details.  You  should  have  received a copy of the GNU General
  12. -- Public  License  along  with  SmallEiffel;  see the file COPYING.  If not,
  13. -- write to the  Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  14. -- Boston, MA 02111-1307, USA.
  15. --
  16. class INSTALL
  17.    --
  18.    -- The portable `install' command to install SmallEiffel. The installation is 
  19.    -- done from scratch. Unless "-no_compile" is specified,  all commands are
  20.    -- recompiled from scratch (the compiler itself is bootstrapped).
  21.    --
  22.  
  23. inherit COMMAND_FLAGS rename system_tools as dev_null end;
  24.  
  25. creation make
  26.  
  27. feature {NONE}
  28.  
  29.    command_name: STRING is "install";
  30.  
  31.    interactive: BOOLEAN;
  32.      -- No automatic compiler selection or system name selection.
  33.  
  34.    no_compile: BOOLEAN;
  35.          -- Compile binaries ? (Useful, if precompile binaries are already
  36.          -- included with a distribution)
  37.  
  38.    compiler: STRING;
  39.          -- Name of C compiler
  40.  
  41.    system_se_path: STRING;
  42.      -- The "system.se" file path is the very first information this 
  43.      -- install program tries to compute. For example, on Windows, the 
  44.      -- value may be "C:SmallEiffel\sys\system.se". This file is intended 
  45.      -- to contains the `system_name' value on its very first line.
  46.  
  47.    set_system_se_path is
  48.       local
  49.      string: STRING;
  50.       do
  51.      echo.put_string("Checking %"SmallEiffel%" environment variable:%N");
  52.      system_se_path := get_environment_variable(fz_se);
  53.      if system_se_path = Void or else system_se_path.count = 0 then
  54.         string := fz_se.twin;
  55.         string.to_upper;
  56.         system_se_path := get_environment_variable(string);
  57.      end;
  58.      if system_se_path = Void or else system_se_path.count = 0 then
  59.         fatal_problem_description_start;
  60.         echo.put_string(
  61.         "Environment variable %"SmallEiffel%" is not set.%N%
  62.         %Please, set this variable with the absolute path of %N%
  63.         %the %"SmallEiffel/sys/system.se%" file.%N%
  64.         %A file %"system.se%" must exists in the sub-directory %"sys%"%
  65.         % of the%NSmallEiffel directory.%N");
  66.         fatal_problem_description_end;
  67.      end;
  68.      if not system_se_path.has_suffix("system.se") then
  69.         fatal_problem_description_start;
  70.         echo.put_string(
  71.         "Value of the Environment variable %"SmallEiffel%"%Nis %"");
  72.         echo.put_string(system_se_path);
  73.         echo.put_string("%".%N");
  74.         echo.put_string(
  75.         "Please, set this variable with the absolute path of%N%
  76.         %the %"SmallEiffel/sys/system.se%" file.%N%
  77.         %For example, on Linux, the value is%N%
  78.         %often %"/usr/lib/SmallEiffel/sys/system.se%".%N%
  79.         %On Windows, %"C:\SmallEiffel\sys\system.se%" is a correct %
  80.         %value%Nwhen the SmallEiffel directory is at toplevel of the C %
  81.         %hard disk.%N");
  82.         fatal_problem_description_end;
  83.      end;
  84.      if not file_exists(system_se_path) then
  85.         fatal_problem_description_start;
  86.         echo.put_string(
  87.         "Value of the Environment variable %"SmallEiffel%" value%Nis %"");
  88.         echo.put_string(system_se_path);
  89.         echo.put_string(
  90.         "%".%N%
  91.         %There is no readable file %"");
  92.         echo.put_string(system_se_path);
  93.         echo.put_string(
  94.         "%".%N%
  95.         %Check this absolute path as well as read permission.%N");
  96.         fatal_problem_description_end;
  97.      end;
  98.      echo.put_string(
  99.      "Value of the Environment variable %"SmallEiffel%" is correctly %
  100.      %set%Nto some existing file%Npath (%"");
  101.      echo.put_string(system_se_path);
  102.      echo.put_string("%").%N");
  103.       end;
  104.  
  105.    installation_path: STRING;
  106.      -- Using the `system_se_path', the `installation_path' of SmallEiffel is 
  107.      -- computed. For example, on Windows, a correct value may be 
  108.      -- "C:\SmallEiffel\".
  109.  
  110.    set_installation_path is
  111.       local
  112.      string: STRING;
  113.       do
  114.      echo.put_string("Checking that the SmallEiffel directory exists:%N");
  115.      string := system_se_path.twin;
  116.      basic_directory.compute_parent_directory_of(string);
  117.      if basic_directory.last_entry.is_empty then
  118.         fatal_problem_description_start;
  119.         echo.put_string("Unable to compute parent directory %Nof %"");
  120.         echo.put_string(system_se_path);
  121.         echo.put_string("%".%N");
  122.         fatal_problem_description_end;
  123.      end;
  124.      string := basic_directory.last_entry.twin;
  125.      basic_directory.compute_parent_directory_of(string);
  126.      if basic_directory.last_entry.is_empty then
  127.         fatal_problem_description_start;
  128.         echo.put_string("Unable to compute parent directory %Nof %"");
  129.         echo.put_string(string);
  130.         echo.put_string("%".%N");
  131.         fatal_problem_description_end;
  132.      end;
  133.      installation_path := basic_directory.last_entry.twin;
  134.      echo.put_string("SmallEiffel directory path is %"");
  135.      echo.put_string(installation_path);
  136.      echo.put_string("%".%N");
  137.       end;
  138.  
  139.    system_name: STRING;
  140.      -- The `system_name' is one element of SYSTEM_TOOLS `system_list' 
  141.      -- ("UNIX", "Windows", "Amiga", etc.).
  142.  
  143.    set_system_name is
  144.       do
  145.      echo.put_string("System name detection:%N");
  146.      if interactive then
  147.         system_name := choice_in("System name selection",
  148.                      system_tools.system_list);
  149.      elseif file_exists("s:startup-sequence") then
  150.         -- This check has to be performed BEFORE the Unix check
  151.         -- ("/bin/ls"), because the latter might be true if the user
  152.         -- installed GeekGadgets and one of those perverted patches
  153.         -- to handle Unix-style paths !
  154.         echo.put_string("System seems to be an Amiga.%N");
  155.         system_name := "Amiga";
  156.      elseif file_exists("/boot/beos/system/Tracker") then
  157.         echo.put_string("System seems to be BeOS.%N");
  158.         system_name := "BeOS";
  159.      elseif file_exists("/bin/ls") then
  160.         echo.put_string("System seems to be UNIX.%N");
  161.         system_name := "UNIX";
  162.      else
  163.         basic_directory.connect_to("C:\");
  164.         if basic_directory.is_connected then
  165.            system_name := "Windows";
  166.            basic_directory.disconnect;
  167.         else
  168.            system_name := choice_in("System name selection",
  169.                     system_tools.system_list);
  170.         end;
  171.      end;
  172.      echo.put_string("System is %"");
  173.      echo.put_string(system_name);
  174.      echo.put_string("%".%NTry to update file %"");
  175.      echo.put_string(system_se_path);
  176.      echo.put_string("%".%N");
  177.      echo.sfw_connect(sfw,system_se_path);
  178.      sfw_check_is_connected(system_se_path);
  179.      sfw.put_string(system_name);
  180.      sfw.put_character('%N');
  181.      sfw.disconnect;
  182.      echo.put_string("Update of %"");
  183.      echo.put_string(system_se_path);
  184.      echo.put_string("%" done.%N")
  185.      system_tools.make;
  186.      if not system_name.is_equal(system_tools.system_name) then
  187.         fatal_problem_description_start;
  188.         echo.put_string("Unkown SYSTEM_TOOLS.system_name %"");
  189.         echo.put_string(system_name);
  190.         echo.put_string("%".%N");
  191.         fatal_problem_description_end;
  192.      end;
  193.       end;
  194.  
  195.    write_default_loadpath_se_file is
  196.      -- Write the appropriate "C:\SmallEiffel\sys\loadpath.se" file.
  197.       local
  198.      path, directory: STRING;
  199.      list: ARRAY[STRING];
  200.      i: INTEGER;
  201.       do
  202.      echo.put_string("Writing default loadpath.se file:%N");
  203.      path := installation_path.twin;
  204.      basic_directory.compute_subdirectory_with(path,"sys");
  205.      if basic_directory.last_entry.is_empty then
  206.         fatal_problem_description_start;
  207.         echo.put_string("Unable to compute subdirectory %"sys%" of %"");
  208.         echo.put_string(path);
  209.         echo.put_string("%".%N");
  210.         fatal_problem_description_end;
  211.      end;
  212.      path.copy(basic_directory.last_entry);
  213.      basic_directory.compute_file_path_with(path,"loadpath.");
  214.      path.copy(basic_directory.last_entry);
  215.      path.append(system_name);
  216.      echo.sfw_connect(sfw,path);
  217.      sfw_check_is_connected(path);
  218.      echo.put_string("--- Written data ---%N");
  219.      -- The current working directory is the very first item:
  220.      if ("UNIX").is_equal(system_name) then
  221.         directory := "./%N";
  222.      elseif ("DOS").is_equal(system_name) then
  223.         directory := ".\%N";
  224.      elseif ("Windows").is_equal(system_name) then
  225.         directory := ".\%N";
  226.      elseif ("BeOS").is_equal(system_name) then
  227.         directory := "./%N";
  228.      elseif ("Macintosh").is_equal(system_name) then
  229.         directory := ":%N";
  230.      elseif ("VMS").is_equal(system_name) then
  231.         -- Don't know the correct notation for VMS, please, if you are 
  232.         -- a VMS user, mail this information to "colnet@loria.fr".
  233.         directory := Void;
  234.      elseif ("OS2").is_equal(system_name) then
  235.         -- Don't know the correct notation for OS2, please, if you are 
  236.         -- a VMS user, mail this information to "colnet@loria.fr".
  237.         directory := Void;
  238.      elseif ("Amiga").is_equal(system_name) then
  239.         directory := "%N";
  240.      end;
  241.      if directory /= Void then
  242.         echo.put_string(directory);
  243.         sfw.put_string(directory);
  244.      end;
  245.      -- After the current working directory, here is the default order 
  246.      -- for searching Eiffel source files :
  247.      list := <<
  248.            "lib_std", 
  249.            "lib_iterator",
  250.            "lib_random", 
  251.            "lib_number",
  252.            "lib_show",
  253.            "lib_se"
  254.            >>;
  255.      from
  256.         i := 1;
  257.      until
  258.         i > list.upper
  259.      loop
  260.         directory := installation_path.twin;
  261.         basic_directory.compute_subdirectory_with(directory,list.item(i));
  262.         directory.copy(basic_directory.last_entry);
  263.         if i < list.upper then
  264.            directory.extend('%N');
  265.         end;
  266.         echo.put_string(directory);
  267.         sfw.put_string(directory);
  268.         i := i + 1;
  269.      end;
  270.      echo.put_string("%N--- Written data ---%N");
  271.      sfw.disconnect;
  272.      echo.put_string("Update of %"");
  273.      echo.put_string(path);
  274.      echo.put_string("%" done.%NThe default loadpath is updated.%N");
  275.       end;
  276.  
  277.    compiler_se_path: STRING;
  278.      -- The path name of the file which is used to save the 
  279.      -- `c_compiler_name' with its default options. For example, 
  280.      -- on Windows, the value may be "C:SmallEiffel\sys\compiler.se"
  281.  
  282.    set_compiler_se_path is
  283.       local
  284.      path: STRING
  285.       do
  286.      path := installation_path.twin;
  287.      basic_directory.compute_subdirectory_with(path,"sys");
  288.      path := basic_directory.last_entry.twin;
  289.      basic_directory.compute_file_path_with(path,"compiler.se");
  290.      compiler_se_path := basic_directory.last_entry.twin;
  291.       end;
  292.  
  293.    garbage_collector_file_path: STRING;
  294.      -- The garbage collector path file. For example, on Windows, a 
  295.      -- correct value may be "C:\SmallEiffel\sys\gc".
  296.  
  297.    set_garbage_collector_file_path is
  298.       local
  299.      path: STRING;
  300.       do
  301.      echo.put_string("Computing GC file path:%N");
  302.      path := installation_path.twin;
  303.      basic_directory.compute_subdirectory_with(path,"sys");
  304.      if basic_directory.last_entry.is_empty then
  305.         fatal_problem_description_start;
  306.         echo.put_string("Unable to compute directory path with %"");
  307.         echo.put_string(path);
  308.         echo.put_string("%" and %"sys%".%N");
  309.         fatal_problem_description_end;
  310.      end;
  311.      path := basic_directory.last_entry.twin;
  312.      basic_directory.compute_file_path_with(path,"gc");
  313.      path := basic_directory.last_entry.twin;
  314.      garbage_collector_file_path := path;
  315.      echo.put_string("GC file path is %"");
  316.      echo.put_string(garbage_collector_file_path);
  317.      echo.put_string("%" and %"sys%".%N");
  318.       end;
  319.  
  320.    garbage_collector: STRING;
  321.      -- The content of the first word of file `garbage_collector_file_path'
  322.      -- (the specific code for the GC).
  323.  
  324.    garbage_collector_selection is
  325.       local
  326.      cmd: STRING;
  327.       do
  328.      echo.put_string("Garbage collector selection:%N");
  329.      if system_name.is_equal("UNIX") then
  330.         cmd := system_se_path.twin;
  331.         cmd.remove_suffix("sys/system.se");
  332.         cmd.append("misc/GC.SH");
  333.         echo.put_string("Launching script %"");
  334.         echo.put_string(cmd);
  335.         echo.put_string("%".%N");
  336.         system(cmd);
  337.      elseif system_name.is_equal("Amiga") then
  338.         garbage_collector := "m68k-amigaos.c";
  339.      elseif system_name.is_equal("Windows") then
  340.         garbage_collector := "windows.c";
  341.      elseif system_name.is_equal("BeOS") then
  342.         garbage_collector := "BeOS_x86.c";
  343.      elseif system_name.is_equal("DOS") then
  344.         garbage_collector := "windows.c";
  345.      elseif system_name.is_equal("Macintosh") then
  346.         garbage_collector := "MacintoshPPC.c";
  347.      elseif system_name.is_equal("OS2") then
  348.         garbage_collector := "windows.c";
  349.      elseif system_name.is_equal("VMS") then
  350.         garbage_collector := "generic.c";
  351.      end;
  352.      if garbage_collector = Void then
  353.         echo.sfr_connect(sfr,garbage_collector_file_path);
  354.         garbage_collector := echo.read_word_in(sfr);
  355.         sfr.disconnect;
  356.         echo.put_string("Selected GC for %"");
  357.         echo.put_string(garbage_collector);
  358.         echo.put_string("%".%N");
  359.      else
  360.         echo.put_string("Selected GC for %"");
  361.         echo.put_string(garbage_collector);
  362.         echo.put_string("%".%N");
  363.         echo.sfw_connect(sfw,garbage_collector_file_path);
  364.         sfw_check_is_connected(garbage_collector_file_path);
  365.         sfw.put_string(garbage_collector);
  366.         sfw.put_character('%N');
  367.         sfw.disconnect;
  368.      end;
  369.       end;
  370.  
  371.    c_compiler_name: STRING;
  372.      -- The `c_compiler_name' is one element of SYSTEM_TOOLS `compiler_list' 
  373.      -- ("gcc", "lcc-win32", "cc", etc.).
  374.  
  375.    c_compiler_linker_options: STRING is "";
  376.      -- Default extra options for the C compiler/linker. 
  377.  
  378.    set_c_compiler_name is
  379.       do
  380.      echo.put_string("C compiler selection:%N");
  381.      if not interactive and compiler = Void then
  382.         if system_name.is_equal("UNIX") then
  383.            compiler := "gcc";
  384.            if ("linux.c").is_equal(garbage_collector) then
  385.           c_compiler_linker_options.copy("-pipe");
  386.            end;
  387.         end;
  388.      end;
  389.      if compiler = Void then
  390.         compiler := choice_in("C compiler selection",
  391.                   system_tools.compiler_list);
  392.      end;
  393.      echo.put_string("Selected C compiler is %"");
  394.      echo.put_string(compiler);
  395.      echo.put_string("%".%N");
  396.      c_compiler_name := compiler;
  397.      echo.put_string("Try to update %"");
  398.      echo.put_string(compiler_se_path);
  399.      echo.put_string("%".%N");
  400.      echo.sfw_connect(sfw,compiler_se_path);
  401.      sfw_check_is_connected(compiler_se_path);
  402.      sfw.put_string(c_compiler_name);
  403.      if interactive then
  404.         interactive_c_compiler_linker_options;
  405.      end;
  406.      if not c_compiler_linker_options.is_empty then
  407.         sfw.put_character(' ');
  408.         sfw.put_string(c_compiler_linker_options);
  409.      end;
  410.      sfw.put_character('%N');
  411.      sfw.disconnect;
  412.      echo.put_string("Update of %"");
  413.      echo.put_string(compiler_se_path);
  414.      echo.put_string("%" done.%N");
  415.      echo.put_string(
  416.      "Hint: It is possible to change some default option(s) for the C %
  417.      %compiler%Njust after the compiler name in the very first line of %
  418.      %the%Nfile %"");
  419.      echo.put_string(compiler_se_path);
  420.      echo.put_string(
  421.      "%".%NFor example, the very first line can be %"gcc -pipe -O3%".%N%
  422.      %If you are no an expert of C compilation, do not add options.%N");
  423.      system_tools.set_c_compiler(Void);
  424.      system_tools.install_extra_options;
  425.       end;
  426.  
  427.    interactive_c_compiler_linker_options is
  428.      -- To set `c_compiler_linker_options' interactively.
  429.       require
  430.      interactive
  431.       do
  432.      std_output.put_string(
  433.      "-----%NIt is possible to add some default option(s) to be passed%N%
  434.      %to the C compiler/linker.%N");
  435.      if ("gcc").is_equal(c_compiler_name) then
  436.         std_output.put_string(
  437.         "With gcc the -pipe option is recommended (unfortunately%N%
  438.             %this is not supported for all platforms).%N%
  439.             %The -pipe option is supported on all Linux platforms.%N")
  440.      end;
  441.      std_output.put_string(
  442.      "Enter now one single line for extra option(s) or an empty line:%N");
  443.      std_input.read_line;
  444.      c_compiler_linker_options.copy(std_input.last_string);
  445.       end;
  446.  
  447.    bin_path: STRING;
  448.      -- The path where binary files are to be placed. For example, 
  449.      -- on Windows, the value may be "C:SmallEiffel\bin\"
  450.  
  451.    set_bin_path is
  452.       do
  453.      bin_path := installation_path.twin;
  454.      basic_directory.compute_subdirectory_with(bin_path,"bin");
  455.      bin_path := basic_directory.last_entry.twin;
  456.      -- Because WinZip may not create an empty directory :
  457.      basic_directory.connect_to(bin_path);
  458.      if basic_directory.is_connected then
  459.         basic_directory.disconnect;
  460.      elseif basic_directory.create_new_directory(bin_path) then
  461.         echo.put_string("Directory %"");
  462.         echo.put_string(bin_path);
  463.         echo.put_string("%" created.%N");
  464.      else
  465.         echo.put_string("Directory %"");
  466.         echo.put_string(bin_path);
  467.         echo.put_string("%" not found.%N");
  468.      end;
  469.       end;
  470.    
  471.    bin_c_path: STRING;
  472.      -- The path where source files are to be found. For example, 
  473.      -- on Windows, the value may be "C:SmallEiffel\bin_c\"
  474.  
  475.    set_bin_c_path is
  476.       do
  477.      bin_c_path := installation_path.twin;
  478.      basic_directory.compute_subdirectory_with(bin_c_path,"bin_c");
  479.      bin_c_path := basic_directory.last_entry.twin;
  480.       end;
  481.  
  482.    bin_path_in_system_env_path: BOOLEAN;
  483.      -- True if we find in the `bin_path' in the system PATH environment 
  484.      -- variable.
  485.  
  486.    compute_bin_path_in_system_env_path is
  487.       local
  488.      se_bin, content: STRING;
  489.       do
  490.      se_bin := bin_path.twin;
  491.      if ("UNIX").is_equal(system_name) then
  492.         content := get_environment_variable("PATH");
  493.         if content /= Void then
  494.            from
  495.           if se_bin.last = '/' then
  496.              se_bin.remove_last(1);
  497.           end;
  498.           content := content.twin;
  499.            variant
  500.           content.count
  501.            until
  502.           content.count = 0
  503.            loop
  504.           if content.has_prefix(se_bin) then
  505.              content.remove_first(se_bin.count);
  506.              if content.count = 0 then
  507.             bin_path_in_system_env_path := true;
  508.              elseif content.first = ':' then
  509.             content.clear;
  510.             bin_path_in_system_env_path := true;
  511.              elseif content.first = '/' then
  512.             content.remove_first(1);
  513.             if content.count = 0 then
  514.                bin_path_in_system_env_path := true;
  515.             elseif content.first = ':' then
  516.                content.clear;
  517.                bin_path_in_system_env_path := true;
  518.             end;
  519.              end;
  520.           else
  521.              content.remove_first(1);
  522.           end;
  523.            end;
  524.         end;
  525.      elseif ("Windows").is_equal(system_name) then
  526.         content := get_environment_variable("PATH");
  527.         if content /= Void then
  528.            from
  529.           if se_bin.last = '\' then
  530.              se_bin.remove_last(1);
  531.           end;
  532.           se_bin.to_lower;
  533.           content := content.twin;
  534.           content.to_lower;
  535.            variant
  536.           content.count
  537.            until
  538.           content.count = 0
  539.            loop
  540.           if content.has_prefix(se_bin) then
  541.              content.remove_first(se_bin.count);
  542.              if content.count = 0 then
  543.             bin_path_in_system_env_path := true;
  544.              elseif content.first = ';' then
  545.             content.clear;
  546.             bin_path_in_system_env_path := true;
  547.              elseif content.first = '\' then
  548.             content.remove_first(1);
  549.             if content.count = 0 then
  550.                bin_path_in_system_env_path := true;
  551.             elseif content.first = ';' then
  552.                content.clear;
  553.                bin_path_in_system_env_path := true;
  554.             end;
  555.              end;
  556.           else
  557.              content.remove_first(1);
  558.           end;
  559.            end;
  560.         end;
  561.      end;
  562.       end;
  563.  
  564.    gathered_information_summary is
  565.       do
  566.      std_output.put_string("---%N%
  567.                    %Summary of gathered information :%N%
  568.                    %   installation_path = %"");
  569.      std_output.put_string(installation_path);
  570.      std_output.put_string("%"%N   system_name = %"");
  571.      std_output.put_string(system_name);
  572.      std_output.put_string("%"%N   c_compiler_name = %"");
  573.      std_output.put_string(c_compiler_name);
  574.      std_output.put_string("%"%N");
  575.      if not c_compiler_linker_options.is_empty then
  576.         std_output.put_string("   c_compiler_linker_options = %"");
  577.         std_output.put_string(c_compiler_linker_options);
  578.         std_output.put_string("%"%N");
  579.      end;
  580.      std_output.put_string("   garbage_collector = %"");
  581.      std_output.put_string(garbage_collector);
  582.      std_output.put_string("%"%N");
  583.      if interactive then
  584.         std_output.put_string(
  585.                "Type <Enter> to continue installation.%N%
  586.            %Type <Enter> now ");
  587.         std_output.flush;
  588.         std_input.read_character;
  589.      end;
  590.      std_output.put_string("---%NSmallEiffel's bootstrap started ...%N");
  591.       end;
  592.  
  593.    move_executable_for(name: STRING) is
  594.      -- Move the executable for command `name' from `bin_c_path' 
  595.      -- to in `bin_path'.
  596.       local
  597.      executable, old_path, new_path: STRING;
  598.       do
  599.      executable := name.twin;
  600.      system_tools.add_x_suffix(executable);
  601.      basic_directory.compute_file_path_with(bin_c_path,executable);
  602.      old_path := basic_directory.last_entry.twin;
  603.      basic_directory.compute_file_path_with(bin_path,executable);
  604.      new_path := basic_directory.last_entry.twin;
  605.      if not file_exists(old_path) then
  606.         fatal_problem_description_start;
  607.         echo.put_string("Unable to find executable %"");
  608.         echo.put_string(old_path);
  609.         echo.put_string("%".%N");
  610.         fatal_problem_description_end;
  611.      end;
  612.      echo.file_renaming(old_path,new_path);
  613.       end;
  614.  
  615.    split_mode_c_compile(name: STRING) is
  616.      -- Assume the current working directory is `bin_c_path', compile some
  617.      -- command `name' produced without the "-no_split" flag.
  618.       local
  619.      c_name: STRING;
  620.      max: INTEGER;
  621.       do
  622.      echo.put_string("C compiling %"");
  623.      echo.put_string(name);
  624.      echo.put_string("*.c%" files.%N");
  625.      run_control.set_output_name(name);
  626.      basic_directory.connect_to_current_working_directory;
  627.      if not basic_directory.is_connected then
  628.         fatal_problem_description_start;
  629.         echo.put_string("Unable to open current working directory.%N");
  630.         fatal_problem_description_end;
  631.      end;
  632.      from
  633.         basic_directory.read_entry;
  634.      until
  635.         basic_directory.end_of_input
  636.      loop
  637.         c_name := basic_directory.last_entry.twin;
  638.         if not c_name.has_prefix(name) then
  639.         elseif not c_name.has_suffix(".c") then
  640.         else
  641.            max := max + 1;
  642.            system_tools.split_mode_c_compiler_command(command,c_name);
  643.            std_output.put_string(command);
  644.            std_output.put_string("%N");
  645.            echo.call_system(command);
  646.         end;
  647.         basic_directory.read_entry;
  648.      end;
  649.      basic_directory.disconnect;
  650.      system_tools.split_mode_linker_command(command,name,max);
  651.      std_output.put_string(command);
  652.      std_output.put_string("%N");
  653.      echo.call_system(command);
  654.      move_executable_for(name);
  655.       end;
  656.  
  657.    call_compile_to_c(options, name: STRING) is
  658.       do
  659.      if bin_path_in_system_env_path then
  660.         command.copy("compile_to_c");
  661.      else
  662.         basic_directory.compute_file_path_with(bin_path,"compile_to_c");
  663.         command.copy(basic_directory.last_entry);
  664.      end;
  665.      system_tools.add_x_suffix(command);
  666.      command.extend(' ');
  667.      command.append(options);
  668.      command.append(" -o ");
  669.      command.append(name);
  670.      command.extend(' ');
  671.      command.append(name);
  672.      std_output.put_string(command);
  673.      std_output.put_string("%N");
  674.      echo.call_system(command);
  675.       end;
  676.  
  677.    prepare_bin_c_directory is
  678.      -- Assume the current working directory is `bin_c_path',
  679.      -- prepare all C source files.
  680.       local
  681.      i: INTEGER;
  682.      item: STRING;
  683.       do
  684.      from
  685.         i := 1;
  686.      until
  687.         i > no_split_command_list.count
  688.      loop
  689.         item := no_split_command_list.item(i);
  690.         if ("lcc-win32").is_equal(c_compiler_name) then
  691.            echo.put_string(
  692.                "Because of the very slow malloc of %"lcc-win32%",%N%
  693.                %the -no_gc flag is not used.%N");
  694.            call_compile_to_c("-boost -no_split",item);
  695.         else
  696.            call_compile_to_c("-boost -no_gc -no_split",item);
  697.         end;
  698.         i := i + 1;
  699.      end;
  700.      from
  701.         i := 1;
  702.      until
  703.         i > splitted_command_list.count
  704.      loop
  705.         item := splitted_command_list.item(i);
  706.         if ("lcc-win32").is_equal(c_compiler_name) then
  707.            echo.put_string(
  708.            "Because of the very slow malloc of %"lcc-win32%" -no_gc flag is not used.%N");
  709.            call_compile_to_c("-boost",item);
  710.         else
  711.            call_compile_to_c("-boost -no_gc",item);
  712.         end;
  713.         i := i + 1;
  714.      end;
  715.       end;
  716.  
  717.    no_split_mode_c_compile(name: STRING) is
  718.      -- Assume the current working directory is `bin_c_path', compile some
  719.      -- command `name' produced with the "-no_split" flag.
  720.       local
  721.      c_name: STRING;
  722.       do
  723.      c_name := name.twin;
  724.      c_name.append(".c");
  725.      run_control.set_output_name(name);
  726.      system_tools.no_split_mode_command(command,c_name);
  727.      std_output.put_string(command);
  728.      std_output.put_character('%N');
  729.      echo.call_system(command);
  730.      move_executable_for(name);
  731.       end;
  732.  
  733.    no_split_command_list: ARRAY[STRING] is
  734.      -- Small commands which can be compiled with the -no_split flag.
  735.       once
  736.      Result := <<
  737.              "clean",
  738.              "compile",
  739.              "finder",
  740.              "print_jvm_class"
  741.              >>;
  742.       end;
  743.  
  744.    splitted_command_list: ARRAY[STRING] is
  745.      -- Small commands which can be compiled with the -no_split flag.
  746.       once
  747.      Result := <<
  748.              "compile_to_c",
  749.              "short",
  750.              "pretty"
  751.              "compile_to_jvm",
  752.              >>;
  753.       end;
  754.  
  755.    c_compile_no_split_command_list is
  756.      -- Apply `no_split_mode_c_compile' for all names of `no_split_command_list'.
  757.       local
  758.      item: STRING;
  759.      i: INTEGER;
  760.       do
  761.      from
  762.         i := 1;
  763.      until
  764.         i > no_split_command_list.count
  765.      loop
  766.         item := no_split_command_list.item(i);
  767.         no_split_mode_c_compile(item);
  768.         i := i + 1;
  769.      end;
  770.       end;
  771.  
  772.    c_compile_splitted_command_list is
  773.      -- Apply `splitted_mode_c_compile' for all names of `splitted_command_list'.
  774.       local
  775.      item: STRING;
  776.      i: INTEGER;
  777.       do
  778.      from
  779.         i := 1;
  780.      until
  781.         i > splitted_command_list.count
  782.      loop
  783.         item := splitted_command_list.item(i);
  784.         split_mode_c_compile(item);
  785.         i := i + 1;
  786.      end;
  787.       end;
  788.  
  789.    fatal_problem_description_start is
  790.       do
  791.      echo.set_verbose;
  792.      echo.put_string(
  793.      "*** Fatal problem during installation of SmallEiffel.%N%
  794.      %    Read carefully the following information before starting%N%
  795.      %    again the `install' -debug command.%N%
  796.      %***************************************************************%N");
  797.       end;
  798.  
  799.    fatal_problem_description_end is
  800.       do
  801.      echo.put_string(
  802.      "***************************************************************%N%
  803.      %Fix the previously described problem and launch again `install'.%N");
  804.      restore_current_working_directory;
  805.      die_with_code(exit_failure_code);
  806.       end;
  807.  
  808.    sfw_check_is_connected(path: STRING) is
  809.       do
  810.      if not sfw.is_connected then
  811.         fatal_problem_description_start;
  812.         echo.put_string("Cannot write file %"");
  813.         echo.put_string(path);
  814.         echo.put_string("%".%NCheck write permissions.");
  815.         fatal_problem_description_end;
  816.      end;
  817.       end;
  818.  
  819.    choice_in(title: STRING; names: ARRAY[STRING]): STRING is
  820.      -- Force some item to be selected interactively.
  821.       local
  822.      i: INTEGER;
  823.      w, n: STRING;
  824.       do
  825.      from
  826.      until
  827.         Result /= Void
  828.      loop
  829.         std_output.put_string(title);
  830.         std_output.put_string(":%N  ");
  831.         from
  832.            i := 1;
  833.         until
  834.            i > names.upper
  835.         loop
  836.            std_output.put_string(names.item(i));
  837.            i := i + 1;
  838.            if i <= names.upper then
  839.           std_output.put_string(", ");
  840.            end;
  841.         end;
  842.         std_output.put_string("%N? ");
  843.         std_output.flush;
  844.         std_input.read_word;
  845.         from
  846.            i := names.lower;
  847.            w := std_input.last_string.twin;
  848.            w.to_lower;
  849.         until
  850.            i > names.upper
  851.         loop
  852.            n := names.item(i).twin;
  853.            n.to_lower;
  854.            if w.is_equal(n) then
  855.           Result := names.item(i);
  856.           i := names.upper;
  857.            elseif n.has_prefix(w) then
  858.           if Result /= Void then
  859.              Result := Void;
  860.           else
  861.              Result := names.item(i);
  862.           end;
  863.            end;
  864.            i := i + 1;
  865.         end;
  866.         if Result = Void then
  867.            std_output.put_string("%"");
  868.            std_output.put_string(w);
  869.            std_output.put_string("%" is not a valid choice.%N");
  870.         end;
  871.      end;
  872.      std_output.put_string("selected: ");
  873.      std_output.put_string(Result);
  874.      std_output.put_string("%N");
  875.       ensure
  876.      Result /= Void;
  877.      names.fast_has(Result)
  878.       end;
  879.  
  880.    echo_usage_exit is
  881.       do
  882.      echo.set_verbose;
  883.      echo.put_string("usage : ");
  884.      echo.put_string(command_name);
  885.          echo.put_string(" [-interactive] [-no_compile] [-compiler <name>] [-debug]%N");
  886.      restore_current_working_directory;
  887.      die_with_code(exit_failure_code);
  888.       end;
  889.  
  890.    basic_directory: BASIC_DIRECTORY;
  891.    
  892.    system_tools: SYSTEM_TOOLS is
  893.       once
  894.      !!Result.install;
  895.       end;
  896.  
  897.    sfr: STD_FILE_READ is
  898.       once
  899.      !!Result.make;
  900.       end;
  901.  
  902.    sfw: STD_FILE_WRITE is
  903.       once
  904.      !!Result.make;
  905.       end;
  906.  
  907.    cwd: STRING;
  908.      -- Used to save the initial current working directory (it 
  909.      -- must be restored before exit using `restore_current_working_directory'
  910.      -- because we are not always under UNIX.
  911.  
  912.    restore_current_working_directory is
  913.       do
  914.      if cwd /= Void then
  915.         basic_directory.change_current_working_directory(cwd);
  916.      end;
  917.       end;
  918.  
  919.    command: STRING is
  920.       once
  921.      !!Result.make(512);
  922.       end;
  923.  
  924.    call_clean(name: STRING) is
  925.       do
  926.      if bin_path_in_system_env_path then
  927.         command.copy("clean");
  928.      else
  929.         basic_directory.compute_file_path_with(bin_path,"clean");
  930.         command.copy(basic_directory.last_entry);
  931.      end;
  932.      system_tools.add_x_suffix(command);
  933.      command.extend(' ');
  934.      command.append(name);
  935.      std_output.put_string(command);
  936.      std_output.put_string("%N");
  937.      echo.call_system(command);
  938.       end;
  939.  
  940.    clean_bin_c_path is
  941.      -- Assume the current working directory is `bin_c_path', compile some
  942.       local
  943.      i: INTEGER;
  944.      item: STRING;
  945.       do
  946.      from
  947.         i := 1;
  948.      until
  949.         i > no_split_command_list.count
  950.      loop
  951.         item := no_split_command_list.item(i);
  952.         call_clean(item);
  953.         i := i + 1;
  954.      end;
  955.      from
  956.         i := 1;
  957.      until
  958.         i > splitted_command_list.count
  959.      loop
  960.         item := splitted_command_list.item(i);
  961.         if not item.is_equal("compile_to_c") then
  962.            call_clean(item);
  963.         end;
  964.         i := i + 1;
  965.      end;
  966.      -- To remove some C compiler specific files :
  967.      basic_directory.connect_to_current_working_directory;
  968.      if basic_directory.is_connected then
  969.         from
  970.            basic_directory.read_entry
  971.         until
  972.            basic_directory.end_of_input
  973.         loop
  974.            item := basic_directory.last_entry.twin;       
  975.            if item.has_prefix("compile_to_c") then
  976.           inspect
  977.               item.last
  978.           when 'h', 'c', 'H', 'C' then
  979.           else
  980.              echo.file_removing(item);
  981.           end;
  982.            else
  983.           echo.file_removing(item);
  984.            end;
  985.            basic_directory.read_entry
  986.         end;
  987.         basic_directory.disconnect;
  988.      end;
  989.      if ("lcc-win32").is_equal(c_compiler_name) then
  990.         echo.put_string("In order to reset %"compile_to_c%" -no_gc in %"");
  991.         echo.put_string(bin_c_path);
  992.         echo.put_string("%".%N");
  993.         call_clean("compile_to_c");
  994.         call_compile_to_c("-boost -no_gc","compile_to_c");
  995.         echo.remove_file("compile_to_c.bat");
  996.      end;
  997.       end;
  998.  
  999.    make is
  1000.       local
  1001.      i: INTEGER;
  1002.      arg: STRING;
  1003.       do
  1004.      from
  1005.         i := 1;
  1006.      until
  1007.         i > argument_count
  1008.      loop
  1009.         arg := argument(i);
  1010.         if ("-debug").is_equal(arg) then
  1011.            echo.set_verbose;
  1012.         elseif ("-interactive").is_equal(arg) then
  1013.            interactive := true;
  1014.         elseif ("-no_compile").is_equal(arg) then
  1015.            no_compile := true;
  1016.         elseif ("-compiler").is_equal(arg) then
  1017.            if i < argument_count then
  1018.           i := i + 1;
  1019.           compiler := argument(i);
  1020.            else
  1021.           std_output.put_string("compiler name must be specified %
  1022.                     %after %"-compiler%"%N");
  1023.           echo_usage_exit;
  1024.                end;
  1025.             else
  1026.               echo_usage_exit;
  1027.             end;
  1028.         i := i + 1;
  1029.      end;
  1030.      std_output.put_string("Install of SmallEiffel started.%N");
  1031.      echo.put_string("Version of command %"");
  1032.      echo.put_string(command_name);
  1033.      echo.put_string("%" is:%N");
  1034.      echo.put_string(small_eiffel.copyright);
  1035.      set_system_se_path;
  1036.      set_installation_path;
  1037.      set_system_name;
  1038.      write_default_loadpath_se_file;
  1039.      set_compiler_se_path;
  1040.      basic_directory.connect_to_current_working_directory;
  1041.      cwd := basic_directory.last_entry.twin;
  1042.      if basic_directory.is_connected then
  1043.         basic_directory.disconnect;
  1044.      end;
  1045.      set_garbage_collector_file_path;
  1046.      garbage_collector_selection;
  1047.      set_c_compiler_name;
  1048.      set_bin_path;
  1049.      set_bin_c_path;
  1050.      basic_directory.change_current_working_directory(bin_c_path);
  1051.      if basic_directory.last_entry.is_empty then
  1052.         fatal_problem_description_start;
  1053.         echo.put_string(
  1054.            "Unable to change current working directory %Nto %"");
  1055.         echo.put_string(bin_c_path);
  1056.         echo.put_string("%".%N");
  1057.         fatal_problem_description_end;
  1058.      end;
  1059.      compute_bin_path_in_system_env_path;
  1060.      gathered_information_summary;
  1061.          if not no_compile then
  1062.            std_output.put_string("C Compiling in %"");
  1063.            std_output.put_string(basic_directory.last_entry);
  1064.            std_output.put_string("%".%N");
  1065.            split_mode_c_compile("compile_to_c");
  1066.            prepare_bin_c_directory;
  1067.            c_compile_no_split_command_list;
  1068.            c_compile_splitted_command_list;
  1069.            clean_bin_c_path;
  1070.          end
  1071.      restore_current_working_directory;
  1072.      if not bin_path_in_system_env_path then
  1073.         std_output.put_string("Do not forget to add %"");
  1074.         std_output.put_string(bin_path);
  1075.         std_output.put_string("%" in %Nyour system path variable.%N");
  1076.      end;
  1077.      std_output.put_string("SmallEiffel installation done.%N");
  1078.      if system_name.is_equal("Windows") then
  1079.         std_output.put_string("Type <Enter> to continue.%N");
  1080.         std_input.read_character;
  1081.      end;
  1082.       end;
  1083.  
  1084. end -- INSTALL
  1085.